package handler

import (
	"context"
	"fmt"
	"log"
	"time"

	"pan/common"
	"pan/config"
	"pan/service/dbproxy/client"
	proto "pan/service/user/proto"
	"pan/util"
)

// User : 用于实现UserServiceHandler接口的对象
type User struct{}

// GenToken : 生成token
func GenToken(username string) string {
	// 40位字符:md5(username+timestamp+token_salt)+timestamp[:8]
	ts := fmt.Sprintf("%x", time.Now().Unix())
	tokenPrefix := util.MD5([]byte(username + ts + "_tokensalt"))
	return tokenPrefix + ts[:8]
}

// Signup : 处理用户注册请求
func (u *User) Signup(ctx context.Context, req *proto.ReqSignup, res *proto.RespSignup) error {
	username := req.Username
	passwd := req.Password

	// 参数简单校验
	if len(username) < 3 || len(passwd) < 5 {
		res.Code = common.StatusParamInvalid
		res.Message = "注册参数无效"
		return nil
	}

	// 对密码进行加盐及取Sha1值加密
	encPasswd := util.Sha1([]byte(passwd + config.PasswordSalt))
	// 将用户信息注册到用户表中
	dbResp, err := client.UserSignup(username, encPasswd)
	if err == nil && dbResp.Suc {
		res.Code = common.StatusOK
		res.Message = "注册成功"
	} else {
		res.Code = common.StatusRegisterFailed
		res.Message = "注册失败"
	}
	return nil
}

// Signin : 处理用户登录请求
func (u *User) Signin(ctx context.Context, req *proto.ReqSignin, res *proto.RespSignin) error {
	username := req.Username
	password := req.Password
	encPasswd := util.Sha1([]byte(password + config.PasswordSalt))
	// 校验用户名及密码
	dbResp, err := client.UserSignin(username, encPasswd)
	log.Println(username, password, encPasswd)
	if err != nil {
		res.Code = common.StatusLoginFailed
		res.Message = err.Error()
		return nil
	}
	if !dbResp.Suc {
		res.Code = common.StatusLoginFailed
		res.Message = dbResp.Msg
		return nil
	}
	// 生成访问凭证(token)
	token := GenToken(username)
	upRes, err := client.UpdateToken(username, token)
	if err != nil || !upRes.Suc {
		res.Code = common.StatusTokenFail
		res.Message = common.StatusText(common.StatusTokenFail)
		return nil
	}
	// 登录成功, 返回token
	res.Code = common.StatusOK
	res.Message = common.StatusText(common.StatusOK)
	res.Token = token
	return nil
}

// UserInfo ： 查询用户信息
func (u *User) UserInfo(ctx context.Context, req *proto.ReqUserInfo, res *proto.RespUserInfo) error {
	// 查询用户信息
	dbResp, err := client.GetUserInfo(req.Username)
	if err != nil {
		res.Code = common.StatusServerError
		res.Message = err.Error()
		return nil
	}
	// 查不到对应的用户信息
	if !dbResp.Suc {
		res.Code = common.StatusUserNotExists
		res.Message = common.StatusText(common.StatusUserNotExists)
		return nil
	}
	user := client.ToTableUser(dbResp.Data)
	// 组装并且响应用户数据
	res.Code = common.StatusOK
	res.Username = user.Username
	res.SignupAt = user.SignupAt
	res.LastActiveAt = user.LastActiveAt
	res.Status = user.UserStatus
	res.Email = user.Email
	res.Phone = user.Phone
	return nil
}
